home *** CD-ROM | disk | FTP | other *** search
- #include <windows.h>
- #include <ddraw.h>
- #include <math.h>
- #include <malloc.h>
- #include "dxproto.h"
- #include "d3d.h"
- #include "appfuncs.h"
- #include "d3dmacs.h"
-
- LPD3DVECTOR
- D3DVECTORNormalise(LPD3DVECTOR v)
- {
- float vx, vy, vz, inv_mod;
- vx = v->x;
- vy = v->y;
- vz = v->z;
- if ((vx == 0) && (vy == 0) && (vz == 0))
- return v;
- inv_mod = (float)(1.0 / sqrt(vx * vx + vy * vy + vz * vz));
- v->x = vx * inv_mod;
- v->y = vy * inv_mod;
- v->z = vz * inv_mod;
- return v;
- }
-
- LPD3DVECTOR
- D3DVECTORCrossProduct(LPD3DVECTOR lpd, LPD3DVECTOR lpa, LPD3DVECTOR lpb)
- {
-
- lpd->x = lpa->y * lpb->z - lpa->z * lpb->y;
- lpd->y = lpa->z * lpb->x - lpa->x * lpb->z;
- lpd->z = lpa->x * lpb->y - lpa->y * lpb->x;
- return lpd;
- }
-
- LPD3DMATRIX
- D3DMATRIXInvert(LPD3DMATRIX d, LPD3DMATRIX a)
- {
- d->_11 = a->_11;
- d->_12 = a->_21;
- d->_13 = a->_31;
- d->_14 = a->_14;
-
- d->_21 = a->_12;
- d->_22 = a->_22;
- d->_23 = a->_32;
- d->_24 = a->_24;
-
- d->_31 = a->_13;
- d->_32 = a->_23;
- d->_33 = a->_33;
- d->_34 = a->_34;
-
- d->_41 = a->_14;
- d->_42 = a->_24;
- d->_43 = a->_34;
- d->_44 = a->_44;
-
- return d;
- }
-
- LPD3DMATRIX
- D3DMATRIXSetRotation(LPD3DMATRIX lpM, LPD3DVECTOR lpD, LPD3DVECTOR lpU)
- {
- float t;
- D3DVECTOR d, u, r;
-
- /*
- * Normalise the direction vector.
- */
- d.x = lpD->x;
- d.y = lpD->y;
- d.z = lpD->z;
- D3DVECTORNormalise(&d);
-
- u.x = lpU->x;
- u.y = lpU->y;
- u.z = lpU->z;
- /*
- * Project u into the plane defined by d and normalise.
- */
- t = u.x * d.x + u.y * d.y + u.z * d.z;
- u.x -= d.x * t;
- u.y -= d.y * t;
- u.z -= d.z * t;
- D3DVECTORNormalise(&u);
-
- /*
- * Calculate the vector pointing along the matrix x axis (in a right
- * handed coordinate system) using cross product.
- */
- D3DVECTORCrossProduct(&r, &u, &d);
-
- lpM->_11 = r.x;
- lpM->_12 = r.y, lpM->_13 = r.z;
- lpM->_21 = u.x;
- lpM->_22 = u.y, lpM->_23 = u.z;
- lpM->_31 = d.x;
- lpM->_32 = d.y;
- lpM->_33 = d.z;
-
- return lpM;
- }
-
- void
- spline(LPD3DVECTOR p, float t, LPD3DVECTOR p1, LPD3DVECTOR p2,
- LPD3DVECTOR p3, LPD3DVECTOR p4)
- {
- double t2, t3;
- float m1, m2, m3, m4;
-
- t2 = (double)(t * t);
- t3 = t2 * (double)t;
-
- m1 = (float)((-1.0 * t3) + (2.0 * t2) + (-1.0 * (double)t));
- m2 = (float)((3.0 * t3) + (-5.0 * t2) + (0.0 * (double)t) + 2.0);
- m3 = (float)((-3.0 * t3) + (4.0 * t2) + (1.0 * (double)t));
- m4 = (float)((1.0 * t3) + (-1.0 * t2) + (0.0 * (double)t));
-
- m1 /= (float)2.0;
- m2 /= (float)2.0;
- m3 /= (float)2.0;
- m4 /= (float)2.0;
-
- p->x = p1->x * m1 + p2->x * m2 + p3->x * m3 + p4->x * m4;
- p->y = p1->y * m1 + p2->y * m2 + p3->y * m3 + p4->y * m4;
- p->z = p1->z * m1 + p2->z * m2 + p3->z * m3 + p4->z * m4;
- }
-
- static D3DEXECUTEDATA d3dExData;
- static LPDIRECT3DEXECUTEBUFFER lpD3DExBuf;
- static D3DEXECUTEBUFFERDESC debDesc;
-
- LPDIRECT3DMATERIAL lpbmat;
- LPDIRECT3DMATERIAL lpmat; /* Material object */
-
- D3DMATRIXHANDLE hProj;
- D3DMATRIX proj = {
- D3DVAL(2.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0),
- D3DVAL(0.0), D3DVAL(2.0), D3DVAL(0.0), D3DVAL(0.0),
- D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0), D3DVAL(1.0),
- D3DVAL(0.0), D3DVAL(0.0), D3DVAL(-1.0), D3DVAL(0.0)
- };
- D3DMATRIXHANDLE hView;
- D3DMATRIX view = {
- D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0),
- D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0),
- D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
- D3DVAL(0.0), D3DVAL(0.0), D3DVAL(10.0), D3DVAL(1.0)
- };
- D3DMATRIXHANDLE hWorld;
- D3DMATRIX world = {
- D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0),
- D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0),
- D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
- D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0)
- };
- D3DMATRIX identity = {
- D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0),
- D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0),
- D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
- D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0)
- };
-
- #define PI 3.14159265359
-
- #define SEGMENTS 40
- #define SIDES 8 /* Number of sides on each ring. */
- #define TEX_RINGS 5 /* Number of rings to stretch the texture over. */
- #define NUM_V (SIDES*(SEGMENTS+1)) // Number of vertices in memory at once
- #define NUM_TRI (SIDES*SEGMENTS*2) // Number of triangles in memory
- #define TUBE_R 1.0 /* Radius of the tube. */
- #define SPLINE_POINTS 50
-
- #define SEGMENT_LENGTH 0.07
- #define SPEED 0.02
- #define DEPTH 0.8
- #define PATH_LENGTH (SPLINE_POINTS - 1)
-
- static struct {
- LPD3DVERTEX lpV; /* Points to the vertices. */
- LPD3DTRIANGLE lpTri; /* Points to the triangles which make up the
- * segments.
- */
- int TriOffset; /* Offset into the execute buffer were the
- * triangle list is found.
- */
- LPD3DVECTOR lpPoints; /* Points to the points defining the spline
- * curve.
- */
- D3DMATERIALHANDLE hMat; /* Handle for the material on the tube. */
- D3DTEXTUREHANDLE hTex; /* Handle for the texture on the material.*/
- D3DLIGHT light; /* Structure defining the light. */
- LPDIRECT3DLIGHT lpD3DLight; /* Object pointer for the light. */
- D3DVECTOR cameraP, cameraD, cameraN; /* Vectors defining the camera
- * position, direction and up.
- */
- float cameraPos; /* Camera position along the
- * spline curve.
- */
- D3DVECTOR endP, endD, endN; /* Vectors defining the position,
- * direction and up at the foremost end of
- * the section in memory.
- */
- float endPos; /* Position along the spline curve of the end. */
- int currentRing, currentSegment; /* Numbers of the ring and tube at
- * the back end of the section.
- */
- } tube;
-
-
- void
- PositionCamera(LPD3DVECTOR lpP, LPD3DVECTOR lpD, LPD3DVECTOR lpN,
- LPD3DMATRIX lpM)
- {
- D3DMATRIX tmp;
-
- tmp._14 = tmp._24 = tmp._34 = tmp._41 = tmp._42 = tmp._43 = (float)0.0;
- tmp._44 = (float)1.0;
- D3DMATRIXSetRotation(&tmp, lpD, lpN);
- D3DMATRIXInvert(lpM, &tmp);
-
- lpM->_41=-(lpM->_11 * lpP->x + lpM->_21 * lpP->y + lpM->_31 * lpP->z);
- lpM->_42=-(lpM->_12 * lpP->x + lpM->_22 * lpP->y + lpM->_32 * lpP->z);
- lpM->_43=-(lpM->_13 * lpP->x + lpM->_23 * lpP->y + lpM->_33 * lpP->z);
- }
-
- void
- MoveToPosition(float position, LPD3DVECTOR lpP, LPD3DVECTOR lpD,
- LPD3DVECTOR lpN)
- {
- LPD3DVECTOR lpSplinePoint[4];
- D3DVECTOR pp, x;
- int i, j;
- float t;
-
- i = 0;
- t = position;
- while (t > 1.0)
- {
- i++;
- if (i == SPLINE_POINTS)
- i = 0;
- t -= (float)1.0;
- }
- for (j = 0; j < 4; j++)
- {
- lpSplinePoint[j] = &tube.lpPoints[i];
- i++;
- if (i == SPLINE_POINTS)
- i = 0;
- }
-
- spline(lpP, t, lpSplinePoint[0], lpSplinePoint[1], lpSplinePoint[2],
- lpSplinePoint[3]);
- spline(&pp, t - (float)0.01, lpSplinePoint[0], lpSplinePoint[1],
- lpSplinePoint[2], lpSplinePoint[3]);
-
- lpD->x = lpP->x - pp.x;
- lpD->y = lpP->y - pp.y;
- lpD->z = lpP->z - pp.z;
- D3DVECTORNormalise(lpD);
-
- D3DVECTORNormalise(lpN);
- D3DVECTORCrossProduct(&x, lpN, lpD);
- D3DVECTORCrossProduct(lpN, &x, lpD);
- lpN->x = -lpN->x;
- lpN->y = -lpN->y;
- lpN->z = -lpN->z;
- D3DVECTORNormalise(lpN);
- }
-
-
- static void
- MakeRing(LPD3DVECTOR p, LPD3DVECTOR d, LPD3DVECTOR n, float tv,
- LPD3DVERTEX joint)
- {
- int spoke;
- float theta, u, v, x, y, z;
- D3DVECTOR nxd;
-
- D3DVECTORCrossProduct(&nxd, n, d);
- for (spoke = 0; spoke < SIDES; spoke++)
- {
- theta = (float)(2.0 * PI) * spoke / SIDES;
- v = (float)sin(theta);
- u = (float)cos(theta);
- x = u * nxd.x + v * n->x;
- y = u * nxd.y + v * n->y;
- z = u * nxd.z + v * n->z;
- joint[spoke].x = (float)TUBE_R * x + p->x;
- joint[spoke].y = (float)TUBE_R * y + p->y;
- joint[spoke].z = (float)TUBE_R * z + p->z;
- joint[spoke].nx = -x;
- joint[spoke].ny = -y;
- joint[spoke].nz = -z;
- joint[spoke].tu = (float)1.0 - theta / (float)(2.0 * PI);
- joint[spoke].tv = tv;
-
- }
- }
-
-
- void
- MakeSegment(int ring1, int ring2, LPD3DTRIANGLE lpTri)
- {
- int side, triangle = 0;
-
- for (side = 0; side < SIDES; side++) {
- /*
- * Each side consists of two triangles.
- */
- lpTri[triangle].v1 = ring1 * SIDES + side;
- lpTri[triangle].v2 = ring2 * SIDES + side;
- lpTri[triangle].v3 = ring2 * SIDES + ((side + 1) % SIDES);
-
- /*
- * for wireframe only need first two edges.
- * Start a two triangle flat fan for each tunnel face.
- */
-
- lpTri[triangle].wFlags = D3DTRIFLAG_STARTFLAT(1);
- lpTri[triangle].wFlags |= D3DTRIFLAG_EDGEENABLE1 |
- D3DTRIFLAG_EDGEENABLE2;
-
- triangle++;
- lpTri[triangle].v2 = ring2 * SIDES + ((side + 1) % SIDES);
- lpTri[triangle].v3 = ring1 * SIDES + ((side + 1) % SIDES);
- lpTri[triangle].v1 = ring1 * SIDES + side;
-
- /*
- * Dont need any edges for wireframe.
- */
- lpTri[triangle].wFlags = D3DTRIFLAG_EVEN;
-
- triangle++;
- }
- }
-
-
- /*
- * Creates a new segment of the tunnel at the current end position.
- * Creates a new ring and segment.
- */
- void
- UpdateTubeInMemory(void)
- {
- static int texRing = 0; /* Static counter defining the position of
- * this ring on the texture.
- */
- int endRing; /* The ring at the end of the tube in memory. */
- int RingOffset, SegmentOffset; /* Offsets into the vertex and triangle
- * lists for the new data.
- */
- /*
- * Replace the back ring with a new ring at the front of the tube
- * in memory.
- */
- memcpy(&tube.lpV[SIDES], &tube.lpV[0], sizeof(tube.lpV[0]) * (NUM_V - SIDES));
- MakeRing(&tube.endP, &tube.endD, &tube.endN, texRing/(float)TEX_RINGS,
- &tube.lpV[0]);
- /*
- * Replace the back segment with a new segment at the front of the
- * tube in memory. Update the current end position of the tube in
- * memory.
- */
- endRing = (tube.currentRing + SEGMENTS) % (SEGMENTS + 1);
- MoveToPosition(tube.endPos, &tube.endP, &tube.endD, &tube.endN);
- /*
- * Update the execute buffer with the new vertices and triangles.
- */
- RingOffset = sizeof(D3DVERTEX) * tube.currentRing * SIDES;
- SegmentOffset = sizeof(D3DTRIANGLE) * tube.currentSegment * SIDES * 2;
- memset(&debDesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
- debDesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
- if (lpD3DExBuf->lpVtbl->Lock(lpD3DExBuf, &debDesc) != D3D_OK)
- return;
- memcpy((char *) debDesc.lpData,
- &tube.lpV[0], sizeof(D3DVERTEX) * NUM_V);
- lpD3DExBuf->lpVtbl->Unlock(lpD3DExBuf);
- /*
- * Update the position of the back of the tube in memory and texture
- * counter.
- */
- tube.currentRing = (tube.currentRing + 1) % (SEGMENTS + 1);
- tube.currentSegment = (tube.currentSegment + 1) % SEGMENTS;
- texRing = (texRing + 1) % TEX_RINGS;
- }
-
-
- /*
- * Move the camera through the tunnel. Create new segments of the tunnel
- * when the camera gets close to the end of the section in memory.
- */
- void
- MoveCamera(LPDIRECT3DDEVICE lpDev, LPDIRECT3DVIEWPORT lpView)
- {
- /*
- * Update the position on curve and camera vectors.
- */
- tube.cameraPos += (float)SPEED;
- if (tube.cameraPos > PATH_LENGTH)
- tube.cameraPos -= PATH_LENGTH;
- MoveToPosition(tube.cameraPos, &tube.cameraP, &tube.cameraD,
- &tube.cameraN);
- /*
- * If the camera is close to the end, add a new segment.
- */
- if (tube.endPos - tube.cameraPos < DEPTH) {
- tube.endPos = tube.endPos + (float)SEGMENT_LENGTH;
- if (tube.endPos > PATH_LENGTH)
- tube.endPos -= PATH_LENGTH;
- UpdateTubeInMemory();
- }
- }
-
-
- /*
- * Modify the buffer between rendering frames
- */
- static void
- TickScene(LPDIRECT3DDEVICE lpDev, LPDIRECT3DVIEWPORT lpView)
- {
- MoveCamera(lpDev, lpView);
- }
-
- D3DRECT RenderScene(LPDIRECT3DDEVICE lpDev, LPDIRECT3DVIEWPORT lpView)
- {
- HRESULT ddrval;
-
- /*
- * Move the camera by updating the view matrix and move the light.
- */
- PositionCamera(&tube.cameraP, &tube.cameraD, &tube.cameraN, &view);
- ddrval = lpDev->lpVtbl->SetMatrix(lpDev, hView, &view);
-
- tube.light.dvPosition.x = tube.cameraP.x;
- tube.light.dvPosition.y = tube.cameraP.y;
- tube.light.dvPosition.z = tube.cameraP.z;
- ddrval = tube.lpD3DLight->lpVtbl->SetLight(tube.lpD3DLight, &tube.light);
-
- ddrval = lpDev->lpVtbl->BeginScene(lpDev);
- ddrval = lpDev->lpVtbl->Execute(lpDev, lpD3DExBuf, lpView, D3DEXECUTE_CLIPPED);
- ddrval = lpDev->lpVtbl->EndScene(lpDev);
- ddrval = lpD3DExBuf->lpVtbl->GetExecuteData(lpD3DExBuf, &d3dExData);
- TickScene(lpDev, lpView);
- return(d3dExData.dsStatus.drExtent);
- }
-
- BOOL
- InitScene(DXDevice *Dev)
- {
- float position; /* Curve position counter. */
- int i; /* counter */
-
- LoadPPMTexture(Dev, "tex1.ppm");
- LoadPPMTexture(Dev, "tex2.ppm");
- LoadPPMTexture(Dev, "tex3.ppm");
- /*
- * Reserved memory for vertices, triangles and spline points.
- */
- tube.lpV = (LPD3DVERTEX) malloc(sizeof(D3DVERTEX) * NUM_V);
- tube.lpTri = (LPD3DTRIANGLE) malloc(sizeof(D3DTRIANGLE) * NUM_TRI);
- tube.lpPoints = (LPD3DVECTOR) malloc(sizeof(D3DVECTOR)*SPLINE_POINTS);
- /*
- * Generate spline points
- */
- for (i = 0; i < SPLINE_POINTS; i++) {
- #if 1
- tube.lpPoints[i].x = (float)(cos(i * 4.0) * 20.0);
- tube.lpPoints[i].y = (float)(sin(i * 4.0) * 20.0);
- tube.lpPoints[i].z = i * (float)20.0;
- #else
- tube.lpPoints[i].x = (float)0.0;
- tube.lpPoints[i].y = (float)0.0;
- tube.lpPoints[i].z = i * (float)20.0;
- #endif
- }
- /*
- * Create the initial tube section in memory.
- */
- tube.endN.x = (float)0.0;
- tube.endN.y = (float)1.0;
- tube.endN.z = (float)0.0;
- position = (float)0.0;
- for (i = 0; i < SEGMENTS + 1; i++) {
- MoveToPosition(position, &tube.endP, &tube.endD, &tube.endN);
- position += (float)SEGMENT_LENGTH;
- MakeRing(&tube.endP, &tube.endD, &tube.endN,
- (float)(i % TEX_RINGS) / TEX_RINGS,
- &tube.lpV[(SEGMENTS - i) * SIDES]);
- }
- for (i = 0; i < SEGMENTS; i++)
- MakeSegment(i + 1, i, &tube.lpTri[i * SIDES * 2]);
- /*
- * Move the camera to the begining and set some globals
- */
- tube.cameraN.x = (float)0.0;
- tube.cameraN.y = (float)1.0;
- tube.cameraN.z = (float)0.0;
- MoveToPosition((float)0.0, &tube.cameraP, &tube.cameraD, &tube.cameraN);
- tube.currentRing = 0;
- tube.currentSegment = 0;
- tube.cameraPos = (float)0.0;
- tube.endPos = position;
- return TRUE;
- }
-
- void
- ReleaseScene(DXDevice *Dev)
- {
- ReleaseAllTextures(Dev);
- if (tube.lpPoints)
- free(tube.lpPoints);
- if (tube.lpTri)
- free(tube.lpTri);
- if (tube.lpV)
- free(tube.lpV);
- }
-
- void
- ReleaseView(LPDIRECT3DVIEWPORT lpView)
- {
- if (lpView)
- lpView->lpVtbl->DeleteLight(lpView, tube.lpD3DLight);
- RELEASE(lpD3DExBuf);
- RELEASE(tube.lpD3DLight);
- RELEASE(lpmat);
- RELEASE(lpbmat);
- }
-
-
- BOOL
- InitView(LPDIRECTDRAW lpDD, LPDIRECT3D lpD3D, LPDIRECT3DDEVICE lpDev,
- LPDIRECT3DVIEWPORT lpView, int NumTextures,
- LPD3DTEXTUREHANDLE TextureHandle)
- {
- /* Variables for exectue buffer generation */
- LPVOID lpBufStart, lpInsStart, lpPointer;
- LPDIRECT3DEXECUTEBUFFER lpD3DExCmdBuf;
- DWORD size;
-
- /* Background material variables */
- D3DMATERIAL bmat;
- D3DMATERIALHANDLE hbmat;
- D3DMATERIAL mat;
-
- /*
- * Set background to black material
- */
- if (lpD3D->lpVtbl->CreateMaterial(lpD3D, &lpbmat, NULL) != D3D_OK)
- return FALSE;
- memset(&bmat, 0, sizeof(D3DMATERIAL));
- bmat.dwSize = sizeof(D3DMATERIAL);
- bmat.dwRampSize = 1;
- lpbmat->lpVtbl->SetMaterial(lpbmat, &bmat);
- lpbmat->lpVtbl->GetHandle(lpbmat, lpDev, &hbmat);
- lpView->lpVtbl->SetBackground(lpView, hbmat);
- /*
- * Set the view, projection and world matricies in an execute buffer
- */
- MAKE_MATRIX(lpDev, hView, view);
- MAKE_MATRIX(lpDev, hProj, proj);
- MAKE_MATRIX(lpDev, hWorld, world);
- /*
- * Create an execute buffer
- */
- size = 0;
- size += sizeof(D3DINSTRUCTION) * 3;
- size += sizeof(D3DSTATE) * 4;
- memset(&debDesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
- debDesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
- debDesc.dwFlags = D3DDEB_BUFSIZE;
- debDesc.dwBufferSize = size;
- if (lpDev->lpVtbl->CreateExecuteBuffer(lpDev, &debDesc, &lpD3DExCmdBuf,
- NULL) != D3D_OK)
- return FALSE;
- if (lpD3DExCmdBuf->lpVtbl->Lock(lpD3DExCmdBuf, &debDesc) != D3D_OK)
- return FALSE;
- lpBufStart = debDesc.lpData;
- memset(lpBufStart, 0, size);
- lpPointer = lpBufStart;
- /*
- * Fill the execute buffer with instructions
- */
- lpInsStart = lpPointer;
- OP_STATE_TRANSFORM(3, lpPointer);
- STATE_DATA(D3DTRANSFORMSTATE_WORLD, hWorld, lpPointer);
- STATE_DATA(D3DTRANSFORMSTATE_VIEW, hView, lpPointer);
- STATE_DATA(D3DTRANSFORMSTATE_PROJECTION, hProj, lpPointer);
- OP_STATE_LIGHT(1, lpPointer);
- STATE_DATA(D3DLIGHTSTATE_AMBIENT, RGBA_MAKE(40, 40, 40, 40), lpPointer);
- OP_EXIT(lpPointer);
- /*
- * Setup the execute data describing the buffer
- */
- lpD3DExCmdBuf->lpVtbl->Unlock(lpD3DExCmdBuf);
- memset(&d3dExData, 0, sizeof(D3DEXECUTEDATA));
- d3dExData.dwSize = sizeof(D3DEXECUTEDATA);
- d3dExData.dwInstructionOffset = (ULONG) 0;
- d3dExData.dwInstructionLength = (ULONG) ((char *)lpPointer - (char*)lpInsStart);
- lpD3DExCmdBuf->lpVtbl->SetExecuteData(lpD3DExCmdBuf, &d3dExData);
- lpDev->lpVtbl->BeginScene(lpDev);
- lpDev->lpVtbl->Execute(lpDev, lpD3DExCmdBuf, lpView, D3DEXECUTE_UNCLIPPED);
- lpDev->lpVtbl->EndScene(lpDev);
- /*
- * We are done with the command buffer.
- */
- lpD3DExCmdBuf->lpVtbl->Release(lpD3DExCmdBuf);
- /*
- * Setup materials and lights
- */
- tube.hTex = TextureHandle[1];
- if (lpD3D->lpVtbl->CreateMaterial(lpD3D, &lpmat, NULL) != D3D_OK)
- return FALSE;
- memset(&mat, 0, sizeof(D3DMATERIAL));
- mat.dwSize = sizeof(D3DMATERIAL);
- mat.diffuse.r = (D3DVALUE)1.0;
- mat.diffuse.g = (D3DVALUE)1.0;
- mat.diffuse.b = (D3DVALUE)1.0;
- mat.diffuse.a = (D3DVALUE)1.0;
- mat.ambient.r = (D3DVALUE)1.0;
- mat.ambient.g = (D3DVALUE)1.0;
- mat.ambient.b = (D3DVALUE)1.0;
- mat.specular.r = (D3DVALUE)1.0;
- mat.specular.g = (D3DVALUE)1.0;
- mat.specular.b = (D3DVALUE)1.0;
- mat.power = (float)20.0;
- mat.dwRampSize = 16;
- mat.hTexture = tube.hTex;
- lpmat->lpVtbl->SetMaterial(lpmat, &mat);
- lpmat->lpVtbl->GetHandle(lpmat, lpDev, &tube.hMat);
- memset(&tube.light, 0, sizeof(D3DLIGHT));
- tube.light.dwSize = sizeof(D3DLIGHT);
- tube.light.dltType = D3DLIGHT_POINT;
- tube.light.dvPosition.x = tube.cameraP.x;
- tube.light.dvPosition.y = tube.cameraP.y;
- tube.light.dvPosition.z = tube.cameraP.z;
- tube.light.dcvColor.r = D3DVAL(0.9);
- tube.light.dcvColor.g = D3DVAL(0.9);
- tube.light.dcvColor.b = D3DVAL(0.9);
- tube.light.dvAttenuation0 = (float)0.0;
- tube.light.dvAttenuation1 = (float)0.0;
- tube.light.dvAttenuation2 = (float)0.05;
- if (lpD3D->lpVtbl->CreateLight(lpD3D, &tube.lpD3DLight, NULL)!=D3D_OK)
- return FALSE;
- if (tube.lpD3DLight->lpVtbl->SetLight(tube.lpD3DLight, &tube.light)
- !=D3D_OK)
- return FALSE;
- if (lpView->lpVtbl->AddLight(lpView, tube.lpD3DLight) != D3D_OK)
- return FALSE;
-
- /*
- * Create an execute buffer
- */
- size = sizeof(D3DVERTEX) * NUM_V;
- size += sizeof(D3DPROCESSVERTICES);
- size += sizeof(D3DINSTRUCTION) * 6;
- size += sizeof(D3DSTATE) * 4;
- size += sizeof(D3DTRIANGLE) * NUM_TRI;
- memset(&debDesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
- debDesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
- debDesc.dwFlags = D3DDEB_BUFSIZE;
- debDesc.dwBufferSize = size;
- if (lpDev->lpVtbl->CreateExecuteBuffer(lpDev, &debDesc, &lpD3DExBuf,
- NULL) != D3D_OK)
- return FALSE;
- /*
- * lock it so it can be filled
- */
- if (lpD3DExBuf->lpVtbl->Lock(lpD3DExBuf, &debDesc) != D3D_OK)
- return FALSE;
- lpBufStart = debDesc.lpData;
- memset(lpBufStart, 0, size);
- lpPointer = lpBufStart;
- VERTEX_DATA(tube.lpV, NUM_V, lpPointer);
- /*
- * Save the location of the first instruction and add instructions to
- * execute buffer.
- */
- lpInsStart = lpPointer;
- OP_STATE_LIGHT(1, lpPointer);
- STATE_DATA(D3DLIGHTSTATE_MATERIAL, tube.hMat, lpPointer);
- OP_PROCESS_VERTICES(1, lpPointer);
- PROCESSVERTICES_DATA(D3DPROCESSVERTICES_TRANSFORMLIGHT, 0, NUM_V, lpPointer);
- OP_STATE_RENDER(3, lpPointer);
- STATE_DATA(D3DRENDERSTATE_TEXTUREHANDLE, tube.hTex, lpPointer);
- STATE_DATA(D3DRENDERSTATE_WRAPU, TRUE, lpPointer);
- STATE_DATA(D3DRENDERSTATE_WRAPV, TRUE, lpPointer);
- /*
- * Make sure that the triangle data (not OP) will be QWORD aligned
- */
- if (QWORD_ALIGNED(lpPointer)) {
- OP_NOP(lpPointer);
- }
- OP_TRIANGLE_LIST(NUM_TRI, lpPointer);
- tube.TriOffset = (char *)lpPointer - (char *)lpBufStart;
- TRIANGLE_LIST_DATA(tube.lpTri, NUM_TRI, lpPointer);
- OP_EXIT(lpPointer);
- /*
- * Setup the execute data describing the buffer
- */
- lpD3DExBuf->lpVtbl->Unlock(lpD3DExBuf);
- memset(&d3dExData, 0, sizeof(D3DEXECUTEDATA));
- d3dExData.dwSize = sizeof(D3DEXECUTEDATA);
- d3dExData.dwVertexCount = NUM_V;
- d3dExData.dwInstructionOffset = (ULONG) ((char *)lpInsStart - (char *)lpBufStart);
- d3dExData.dwInstructionLength = (ULONG) ((char *)lpPointer - (char *)lpInsStart);
- lpD3DExBuf->lpVtbl->SetExecuteData(lpD3DExBuf, &d3dExData);
-
- return TRUE;
- }
-